import React, {Component} from 'react';
import { observable, action, computed, autorun, toJS } from 'mobx';
import {Tools, Bubble, Toast } from 'weaver-mobile';
import { MapPage } from 'weaver-mobile-page';
import isEmpty from 'lodash/isEmpty';
import has from 'lodash/has';
import findIndex from 'lodash/findIndex';
import * as api from '../apis/sign';
import {formatUrl} from './public-func';
import moment from 'moment';

window.companyIconUrl = "/hrm/hrm_e9/images/sign/marker_company.png";
window.selfIconUrl = "/hrm/hrm_e9/images/sign/marker_self.png";

export default class MapUtil{
    @observable mapStore = new MapPage.Store();

    amap;//高德地图实例
    markers = [];//google map's marker collection
    circles = [];//google map's circle collection
    polyline;//google map's polyline

    constructor(type){
        !isEmpty(type) && this.setMapType(type);
    }

    get regeoUrl(){//regeo url
        let url = '';
        if(this.isAmap){
            url = 'https://restapi.amap.com/v3/geocode/regeo';
        }else if(this.isGoogleMap){
            url = 'https://maps.googleapis.com/maps/api/geocode/json';
        }
        return url;
    }

    //获取最后一次使用的地图类型
    // getLast

    //#region 地图初始化状态
    @observable _mapInited = false;
    @computed get mapInited(){return this._mapInited}
    set mapInited(v){this._mapInited = v}
    //#endregion

    //#region 设置地图实例
    get mapInstance(){
        if(this.isAmap)
            return this.amap;
        else if(this.isGoogleMap){
            return this.googleMapStore.map;
        }
    }

    set mapInstance(v){
        this.amap = v;
        this.mapInited = true;
    }
    //#endregion

    //#region 地图属性
    //获取地图配置信息
    get defaultMapParams(){
        return this.mapStore.getDefaultMapParams();
    }

    //当前地图类型
    @computed get currentMapType(){
        return this.mapStore.mapType || this.defaultMapParams.defaultMap;
    }

    //是否是高德地图
    @computed get isAmap(){
        return this.currentMapType.toLowerCase() === 'gaode';
    }

    //是否是google地图
    @computed get isGoogleMap(){
        return this.currentMapType.toLowerCase() === 'google';
    }

    //google地图store
    @computed get googleMapStore(){
        return this.mapStore.googleMapStore;
    }

    //高德地图webservice key
    get amapWebServiceKey(){
        try{
            return this.defaultMapParams.gaodeMapWebServiceKey;
        }catch(e){
            return '';
        }
    }

    //google地图key
    get googleMapKey(){
        try{
            return this.defaultMapParams.googleMapKey;
        }catch(e){
            return '';
        }
    }
    //#endregion

    //#region 地图操作
    //设置地图类型
    setMapType = type => !isEmpty(type) && this.mapStore.setMapType(type);
    //#endregion

    //地图类型切换事件
    onMapTypeChangeHandle = async (type, callback) => {
        this.mapInited = false;
        const data = await api.resetUserMap({user_last_map: type});
        if(data.status != '1')
            Bubble.error(data.message);
        else
            callback && callback();
    }

    //创建marker icon
    createIcon = image => {
        if(this.isAmap){
            return new window.AMap.Icon({
                image,
                // 图标尺寸
                size: new window.AMap.Size(36, 36),
                // 图标所用图片大小
                imageSize: new window.AMap.Size(36, 36),
            })
        }else if(this.isGoogleMap){
            return {
                url: image,
                scaledSize: new window.google.maps.Size(32, 32),
            }
        }
    }

    //清除marker
    clearMarker = id => {
        if(this.isAmap){
            let overlays = this.mapInstance.getAllOverlays("marker");
            if(id){
                overlays.map(overlay => {
                    const extData = overlay.getExtData();
                    if(has(extData, "id") && (extData.id == id)){
                        this.mapInstance.remove(overlay);
                    }
                });
            }else{
                overlays.map(overlay => {
                    this.mapInstance.remove(overlay);
                });
            }
        }else if(this.isGoogleMap){
            if(id){
                const idx = findIndex(this.markers, {extData: {id}});
                if(idx > -1){
                    this.markers[idx].setMap(null);
                    this.markers.splice(idx, 1);
                }
            }
            console && console.debug(this.markers);
            // if(markerGoogle){
            //     markerGoogle.setMap(null);
            // }
        }
    }

    //添加marker
    addMarker = (data, icon, offset, otherParams = {}) => {
        const markerProps = {};
        const {latitude, longitude, id} = data;
        let marker;
        if(this.isAmap){
            Object.assign(markerProps, {position: new window.AMap.LngLat(longitude, latitude)});
            id && Object.assign(markerProps, {extData: {id}});
            icon && Object.assign(markerProps, {icon});
            offset && Object.assign(markerProps, {offset});
            Object.assign(markerProps, otherParams);
            marker = new window.AMap.Marker(markerProps);
            this.mapInstance.add(marker);
        }else if(this.isGoogleMap){
            Object.assign(markerProps, {position: {lng:Number(longitude), lat:Number(latitude)}});
            icon && Object.assign(markerProps, {icon});
            Object.assign(markerProps, otherParams);
            marker = this.googleMapStore.newMarker(markerProps);
            id && Object.assign(marker, {extData: {id}});
            console && console.debug(marker)
            this.markers.push(marker);
        }
        return marker;
    }

    //清除circle
    clearCircle = id => {
        if(this.isAmap){
            let overlays = this.mapInstance.getAllOverlays("circle");
            if(id){
                overlays.map(overlay => {
                    const extData = overlay.getExtData();
                    if(has(extData, "id") && (extData.id == id)){
                        this.mapInstance.remove(overlay);
                    }
                });
            }else{
                overlays.map(overlay => {
                    this.mapInstance.remove(overlay);
                });
            }
        }else if(this.isGoogleMap){
            console && console.debug(this.circles);
            // if(markerGoogle){
            //     markerGoogle.setMap(null);
            // }
        }
    }

    //添加circle
    addCircle = (data, otherParams = {}) => {
        const circleProps = {};
        const {latitude, longitude, radius, id} = data;
        let circle;
        if(this.isAmap){
            Object.assign(circleProps, {
                center: new window.AMap.LngLat(longitude, latitude), // 圆心位置
                radius:  radius || 100,//半径
                strokeColor: otherParams.strokeColor || "#55B1F9", //线颜色
                strokeOpacity: otherParams.strokeOpacity || 1, //线透明度
                strokeWeight: otherParams.strokeWeight || 2, //线粗细度
                fillColor: otherParams.fillColor || "#55b1f9", //填充颜色
                fillOpacity: otherParams.fillOpacity || 0.2, //填充透明度,
                ...otherParams
            });
            id && Object.assign(circleProps, {extData: {id}});
            circle = new window.AMap.Circle(circleProps);
            this.mapInstance.add(circle);
        }else if(this.isGoogleMap){
            Object.assign(circleProps, {
                center: {lng:Number(longitude), lat:Number(latitude)}, // 圆心位置
                radius: radius || 500,//locationcheckscope, //半径
                strokeColor: otherParams.strokeColor || "#55B1F9", //线颜色
                strokeOpacity: otherParams.strokeOpacity || 1, //线透明度
                strokeWeight: otherParams.strokeWeight || 2, //线粗细度
                fillColor: otherParams.fillColor || "#55b1f9", //填充颜色
                fillOpacity: otherParams.fillOpacity || 0.2, //填充透明度,
                ...otherParams
            });
            id && Object.assign(circleProps, {extData: {id}});
            circle = this.googleMapStore.newCircle(circleProps)
            this.circles.push(circle);
        }
        return circle;
    }

    //清除polyline
    clearPolyline = () => {
        
    }

    //添加polyline
    addPolyline = (path, otherParams = {}) => {
        let polyline;
        if(this.isAmap){
            polyline = new window.AMap.Polyline({
                path,
                strokeColor: otherParams.strokeColor || '#55B1F9',
                ...otherParams
            });
            this.mapInstance.add(polyline);
        }else if(this.isGoogleMap){
            polyline = this.googleMapStore.newPolyline({
                path,
                geodesic: otherParams.strokeColor || true,
                strokeColor: otherParams.strokeColor || '#FF0000',
                strokeOpacity: otherParams.strokeColor || 1.0,
                strokeWeight: otherParams.strokeColor || 2,
                ...otherParams
            })
            this.googleMapStore.showCover(polyline);
        }
        return polyline;
    }

    //清除地图所有数据
    clearMapData = () => {
        if(this.isAmap){
            this.mapInstance.clearMap();
        }else if(this.isGoogleMap){
            this.markers.map(m => this.googleMapStore.clearCover(m));
            this.circles.map(m => this.googleMapStore.clearCover(m));
            this.polyline && this.googleMapStore.clearCover(this.polyline);
            this.markers.length = 0;
            this.circles.length = 0;
            this.polyline = null;
        }
    }

    //设置地图中心
    setCenter = data => {
        let position;
        if(this.isAmap){
            position = new window.AMap.LngLat(
                data.longitude,
                data.latitude
            )
            this.mapInstance.setCenter(position);
        }else if(this.isGoogleMap){
            position = {
                lng:Number(data.longitude),
                lat:Number(data.latitude)
            }
            this.googleMapStore.setCenter(position);
        }
    }

    //fit view
    setFitView = datas => {
        setTimeout(() => {
            if(this.isAmap){
                this.mapInstance.setFitView(datas, null, null, 18);
            }else if(this.isGoogleMap){
                const dataLen = datas.length;
                if(dataLen > 1){
                    let bounds = new window.google.maps.LatLngBounds();
                    datas.map(d => {
                        bounds.extend(new window.google.maps.LatLng(Number(d.latitude), Number(d.longitude)));
                    })
                    this.googleMapStore.fitBounds(bounds);
                }else{
                    this.googleMapStore.setCenter({lat:Number(datas[0].latitude), lng:Number(datas[0].longitude)});
                }
            }
        }, 50);
    }
    //#endregion

    //#region 逆地址解析
    @action regeo = async (locationInfo, regeoParams = {}) => {
        return new Promise((resolve, reject) => {
            const {longitude, latitude} = locationInfo;
            const flag = isEmpty(longitude + '') || isEmpty(latitude + '');
            if(!flag){
                const {radius, poitype} = regeoParams || {};
                let req, params = {};
                if(this.isAmap){
                    params = {
                        key: this.amapWebServiceKey,
                        location: `${longitude},${latitude}`,
                        radius: radius || 1000,
                        poitype: poitype || '',
                        extensions: 'all',
                        batch: 'false',
                        roadlevel: '0'
                    }
                }else if(this.isGoogleMap){
                    params = {
                        key: this.googleMapKey,
                        latlng: `${latitude},${longitude}`,
                        radius: radius || 1000,
                        poitype: poitype || '',
                        extensions: 'all',
                        batch: 'false',
                        roadlevel: '0'
                    }
                }
                localStorage.setItem('regeoParams', `regeoParams-${moment().format("yyyy-MM-dd HH:mm:ss")}: ${JSON.stringify(params)}`);
                const url = `${this.regeoUrl}${formatUrl(params)}`;
                fetch(url, {method: 'GET'})
                .then(res => res.json())
                .catch(error => {
                    Bubble.error(<div onClick={() => Bubble.error(JSON.stringify(error))}>call amap regeo failed</div>);
                    resolve({address: ''});
                })
                .then(data => {
                    let address = '';
                    if(data.status == '1' || data.status == 'OK'){
                        if(this.isAmap){
                            let {formatted_address = ''} = data.regeocode || {};
                            address = formatted_address;
                        }else if(this.isGoogleMap){
                            if(data.results.length > 0){
                                let {formatted_address = ''} = data.results[0];
                                address= formatted_address;
                            }
                        }
                    }else{
                        Bubble.error(JSON.stringify(data));
                    }
                    resolve({...locationInfo, address});
                })
            }
        })
    }
    //#endregion

    queryLocations = async (data) => new Promise((resolve, reject) => {
        const {longitude, latitude, radius, types, page} = data;
        const params = {
            key: this.amapWebServiceKey,
            location: `${longitude},${latitude}`,
            radius,
            types,
            page,
            offset: window.queryLocationPageSize || 50,
            extensions:'all'
        }
        localStorage.setItem('aroundParams', `aroundParams-${moment().format("yyyy-MM-dd HH:mm:ss")}: ${JSON.stringify(params)}`);
        const url = `https://restapi.amap.com/v3/place/around${formatUrl(params)}`;
        fetch(url, {method: 'GET'})
        .then(res => res.json())
        .catch(error => {
            Bubble.error(<div onClick={() => Bubble.error(JSON.stringify(error))}>call amap around failed</div>);
            resolve([]);
        })
        .then(data => {
            if(data.status == '1'){
                const list = data.pois.map((p, idx) => {
                    const [longitude, latitude] = p.location.split(',');
                    const {pname = '', cityname = '', adname = '', bussiness_area = '', address = ''} = p;
                    let cityName = (pname == cityname ? cityname : `${pname}${cityname}`);
                    return {
                        id: ((page || 1) - 1) * 50 + idx,
                        name: p.name,
                        address: `${cityName}${adname}${bussiness_area}${address}`,
                        longitude,
                        latitude
                    }
                })
                resolve(list);
            }else{
                Bubble.error(JSON.stringify(data));
                resolve([]);
            }
        })
    })
}